home *** CD-ROM | disk | FTP | other *** search
/ The Atari Compendium / The Atari Compendium (Toad Computers) (1994).iso / files / prgtools / gnustuff / tos / updates / update18.zoo / libg++ / src / streambu.cc < prev    next >
Encoding:
C/C++ Source or Header  |  1992-03-22  |  5.3 KB  |  278 lines

  1. //    This is part of the iostream library, providing input/output for C++.
  2. //    Copyright (C) 1991, 1992 Per Bothner.
  3. //
  4. //    This library is free software; you can redistribute it and/or
  5. //    modify it under the terms of the GNU Library General Public
  6. //    License as published by the Free Software Foundation; either
  7. //    version 2 of the License, or (at your option) any later version.
  8. //
  9. //    This library is distributed in the hope that it will be useful,
  10. //    but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. //    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  12. //    Library General Public License for more details.
  13. //
  14. //    You should have received a copy of the GNU Library General Public
  15. //    License along with this library; if not, write to the Free
  16. //    Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  17.  
  18. #define _STREAM_COMPAT
  19. #ifdef __GNUG__
  20. #pragma implementation
  21. #endif
  22. #include "ioprivat.h"
  23.  
  24. #ifdef atarist
  25. // for the atari we take a hit here so that bin/text modes are taken care of
  26. // automatically by sputc/sbumpc
  27.  
  28. size_t streambuf::sputn(const char* s, size_t n) // OPTIMIZE THIS!
  29. {
  30.     size_t count = 0;
  31.     for (; count < n; count++) {
  32.     if (sputc(*s++) == EOF)
  33.         break;
  34.     }
  35.     return count;
  36. }
  37.  
  38. size_t streambuf::sgetn(char* s, size_t n) // OPTIMIZE THIS!
  39. {
  40.     size_t count = 0;
  41.     for (; count < n; count++) {
  42.     int ch = sbumpc();
  43.     if (ch == EOF)
  44.         break;
  45.     *s++ = ch;
  46.     }
  47.     return count;
  48. }
  49. #else
  50. size_t streambuf::sputn(register const char* s, size_t n)
  51. {
  52.     register size_t more = n;
  53.     for (;;) {
  54.     size_t count = _epptr - _pptr; // Space available.
  55.     if (count > 0) {
  56.         if (count > more)
  57.         count = more;
  58.         if (count > 20) {
  59.         memcpy(_pptr, s, count);
  60.         s += count;
  61.         _pptr += count;
  62.         }
  63.         else if (count <= 0)
  64.         count = 0;
  65.         else {
  66.         register char *p = _pptr;
  67.         for (register long i = count; --i >= 0; ) *p++ = *s++;
  68.         _pptr = p;
  69.         }
  70.         more -= count;
  71.     }
  72.     if (more == 0 || overflow(*s++) == EOF)
  73.         break;
  74.     more--;
  75.     }
  76.     return n - more;
  77. }
  78.  
  79. size_t streambuf::sgetn(char* s, size_t n)
  80. {
  81.     register size_t more = n;
  82.     for (;;) {
  83.     size_t count = _egptr - _gptr; // Data available.
  84.     if (count > 0) {
  85.         if (count > more)
  86.         count = more;
  87.         if (count > 20) {
  88.         memcpy(s, _gptr, count);
  89.         s += count;
  90.         _gptr += count;
  91.         }
  92.         else if (count <= 0)
  93.         count = 0;
  94.         else {
  95.         register char *p = _gptr;
  96.         for (register long i = count; --i >= 0; ) *s++ = *p++;
  97.         _gptr = p;
  98.         }
  99.         more -= count;
  100.     }
  101.     if (more == 0)
  102.         break;
  103.     int c = underflow();
  104.     if (c == EOF)
  105.         break;
  106.     *s++ = c;
  107.     more--;
  108.     }
  109.     return n - more;
  110. }
  111. #endif
  112.  
  113. int streambuf::sync()
  114. {
  115.     if (gptr() == egptr() && pptr() == pbase())
  116.     return 0;
  117.     return EOF;
  118. }
  119.  
  120. int streambuf::pbackfail(int c)
  121. {
  122.     return EOF;
  123. }
  124.  
  125. int streambuf::ungetfail()
  126. {
  127.     if (seekoff(-1, ios::cur, ios::in) == EOF)
  128.     return EOF;
  129.     return sgetc();
  130. }
  131.  
  132. streambuf* streambuf::setbuf(char* p, size_t len)
  133. {
  134.     setb(p, p+len, 0);
  135.     setp(0, 0);
  136.     setg(0, 0, 0);
  137.     return this;
  138. }
  139.  
  140. streampos streambuf::seekpos(streampos pos, int mode)
  141. {
  142.     return seekoff(pos, ios::beg, mode);
  143. }
  144.  
  145. void streambuf::setb(char* b, char* eb, int a)
  146. {
  147.     if (_base && (_flags & _S_USER_BUF))
  148.     FREE_BUF(_base);
  149.     _base = b;
  150.     _ebuf = eb;
  151.     if (a)
  152.     _flags &= ~_S_USER_BUF;
  153.     else
  154.     _flags |= _S_USER_BUF;
  155. }
  156.  
  157. #ifdef atarist
  158. extern "C" { extern unsigned long __DEFAULT_BUFSIZ__; }
  159.  
  160. int streambuf::doallocate()
  161. {
  162.     char *buf = malloc((size_t)__DEFAULT_BUFSIZ__);
  163.     if (buf == NULL)
  164.     return EOF;
  165.     setb(buf, buf+__DEFAULT_BUFSIZ__, 1);
  166.     return 1;
  167. }
  168. #else
  169. int streambuf::doallocate()
  170. {
  171.     char *buf = ALLOC_BUF(BUFSIZ);
  172.     if (buf == NULL)
  173.     return EOF;
  174.     setb(buf, buf+BUFSIZ, 1);
  175.     return 1;
  176. }
  177. #endif
  178.  
  179. #ifdef atarist
  180. extern "C" extern int __default_mode__;
  181. #endif
  182.  
  183. streambuf::streambuf()
  184. {
  185. #ifdef atarist
  186.   _flags = _IO_MAGIC | ((__default_mode__)? _S_IS_BINARY : 0);
  187. #else
  188.   _flags = _IO_MAGIC;
  189. #endif
  190.   _base = NULL;
  191.   _ebuf = NULL;
  192.   _eback = NULL;
  193.   _gptr = NULL;
  194.   _egptr = NULL;
  195.   _pbase = NULL;
  196.   _pptr = NULL;
  197.   _epptr = NULL;
  198.   _chain = NULL; // Not necessary.
  199. }
  200.  
  201. streambuf::~streambuf()
  202. {
  203.     if (_base && !(_flags & _S_USER_BUF))
  204.     FREE_BUF(_base);
  205. }
  206.  
  207. int streambuf::underflow()
  208. {
  209.     return EOF;
  210. }
  211.  
  212. int streambuf::overflow(int c = EOF)
  213. {
  214.     return EOF;
  215. }
  216.  
  217. streampos
  218. streambuf::seekoff(streamoff, _seek_dir, int mode /*=ios::in|ios::out*/)
  219. {
  220.     return EOF;
  221. }
  222.  
  223. int streambuf::sputbackc(char c)
  224. {
  225.     if (gptr() <= eback()) return pbackfail(c);
  226.     gbump(-1);
  227.     if (*gptr() != c)
  228.     *gptr() = c;
  229.     return (unsigned char)c;
  230. }
  231.  
  232. int streambuf::sungetc()
  233. {
  234.     if (gptr() > eback()) {
  235.     gbump(-1);
  236.     return (unsigned char)*gptr();
  237.     }
  238.     else
  239.     return ungetfail();
  240. }
  241.  
  242. #if 0 /* Work in progress */
  243. void streambuf::collumn(int c)
  244. {
  245.     if (c == -1)
  246.     _collumn = -1;
  247.     else
  248.     _collumn = c - (_pptr - _pbase);
  249. }
  250. #endif
  251.  
  252. int streambuf::flush_all()
  253. {
  254.     int result = 0;
  255.     for (streambuf *sb = _list_all; sb != NULL; sb = sb->xchain())
  256.     if (sb->overflow(EOF) == EOF)
  257.         result = EOF;
  258.     return result;
  259. }
  260.  
  261. void streambuf::flush_all_linebuffered()
  262. {
  263.     for (streambuf *sb = _list_all; sb != NULL; sb = sb->xchain())
  264.     if (sb->linebuffered())
  265.         sb->sync();
  266. }
  267.  
  268.  
  269. #ifdef IO_CLEANUP
  270.   IO_CLEANUP
  271. #else
  272. struct __io_defs {
  273.     __io_defs() { }
  274.     ~__io_defs() { streambuf::flush_all(); }
  275. };   
  276. __io_defs io_defs__;
  277. #endif
  278.